#include "PreCompile.hpp"
#include "WeakPtrTests.hpp"

namespace BuildNG
{
  class WeakPtrTestObject : public Object
  {
  public:
    WeakPtrTestObject(int *flag)
      : flag(flag)
    {
      *flag = 0;
    }

    ~WeakPtrTestObject()
    {
      *flag = 1;
    }

    int *flag;

  };

  void WeakPtrTests::basic_test()
  {
    int flag;
    WeakPtr<WeakPtrTestObject> weakptr;

    {
      Glib::RefPtr<WeakPtrTestObject> object(new WeakPtrTestObject(&flag));
      weakptr = object;

      Glib::RefPtr<WeakPtrTestObject> acquired = weakptr.acquire();
      assert(acquired == object);

      assert(flag == 0);    // the object should not be freed yet
    }
    assert(flag == 1);    // the object should be freed

    Glib::RefPtr<WeakPtrTestObject> acquired2 = weakptr.acquire();
    assert(!acquired2);
  }

  void WeakPtrTests::test_acquired_kept_alive()
  {
    int flag;

    {
      Glib::RefPtr<WeakPtrTestObject> through_acquire;

      {
        Glib::RefPtr<WeakPtrTestObject> obj(new WeakPtrTestObject(&flag));

        WeakPtr<WeakPtrTestObject> weak_ptr = obj;

        through_acquire = weak_ptr.acquire();
      }

      assert(flag == 0);
    }
    assert(flag == 1);
  }

  void WeakPtrTests::test_copy_weakptr()
  {
    int flag;

    WeakPtr<WeakPtrTestObject> *ptr2 = 0;

    {
      Glib::RefPtr<WeakPtrTestObject> obj(new WeakPtrTestObject(&flag));

      {
        WeakPtr<WeakPtrTestObject> ptr1 = obj;
        ptr2 = new WeakPtr<WeakPtrTestObject>(ptr1);
      }
      assert(ptr2->acquire() == obj);

      assert(flag == 0);
    }
    assert(flag == 1);
    assert(!ptr2->acquire());
    delete ptr2;
  }

  void WeakPtrTests::test_assign_weakptr()
  {
    int flag;

    WeakPtr<WeakPtrTestObject> ptr2;
    {
      Glib::RefPtr<WeakPtrTestObject> obj(new WeakPtrTestObject(&flag));

      {
        WeakPtr<WeakPtrTestObject> ptr1 = obj;
        ptr2 = ptr1;
      }
      assert(ptr2.acquire() == obj);

      assert(flag == 0);
    }
    assert(flag == 1);
    assert(!ptr2.acquire());
    ptr2.clear();
  }
}